البرمجة

شجرة DOM وجافاسكربت

التعرف على شجرة DOM لتعديلها عبر جافاسكربت

في عالم تطوير الويب، تُعد شجرة DOM (Document Object Model) أحد المفاهيم الأساسية التي يجب على كل مطوّر فهمها بعمق، خصوصًا عند التعامل مع التفاعل الديناميكي بين المستخدم وصفحات الويب. شجرة DOM ليست مجرد تمثيل للصفحة، بل هي البوابة التي تمكن المطور من قراءة وتعديل هيكلية المحتوى، وتغيير عناصر الصفحة، والتفاعل مع الأحداث، وذلك باستخدام جافاسكربت باعتبارها اللغة الأكثر استخدامًا في هذا السياق.

هذا المقال يتناول بشكل موسع وشامل مفهوم شجرة DOM، بنيتها، طرق الوصول إليها، التعديل عليها، أنواع العقد، الأحداث المرتبطة بها، وتأثير كل ذلك على تجربة المستخدم وبنية التطبيقات الحديثة.


أولًا: ما هي شجرة DOM؟

DOM هو اختصار لـ Document Object Model، أي نموذج كائني لوثيقة HTML أو XML. وهي واجهة برمجية تتيح للغات البرمجة، مثل جافاسكربت، التعامل مع بنية المستندات بطريقة كائنية (Object-Oriented).

عند تحميل صفحة ويب في المتصفح، يقوم المتصفح بتحليل وثيقة HTML وتحويلها إلى شجرة من الكائنات التي تمثل العناصر والعُقد الموجودة في الصفحة، وتُعرف هذه الشجرة بـ “شجرة DOM”.

تُشكّل هذه الشجرة تمثيلًا هرميًا يُمكن التفاعل معه برمجيًا. تتكون الشجرة من أنواع مختلفة من العقد (Nodes)، منها:

  • العقدة الجذرية (Root Node): تمثل المستند بأكمله.

  • عُقد العناصر (Element Nodes): تمثل العناصر مثل

    ,

    ,

      , إلخ.

    • عُقد النصوص (Text Nodes): تمثل النص الموجود داخل العناصر.

    • عُقد التعليقات (Comment Nodes): تمثل التعليقات المكتوبة في HTML.


    ثانيًا: بنية شجرة DOM

    شجرة DOM تتخذ شكلًا هرميًا يشبه شجرة عائلة، تبدأ من عنصر جذر (عادةً ) وتتفرع إلى عناصر فرعية:

    html
    html> <html> <head> <title>مثالtitle> head> <body> <h1>مرحباh1> <p>هذه فقرة.p> body> html>

    يتم تمثيل هذه الصفحة كشجرة DOM كالتالي:

    • Document

      • html

        • head

          • title

            • نص: “مثال”

        • body

          • h1

            • نص: “مرحبا”

          • p

            • نص: “هذه فقرة.”

    كل عقدة لها علاقة هرمية بالأخرى، مثل الأب، الابن، الشقيق، إلخ.


    ثالثًا: طرق الوصول إلى عناصر DOM باستخدام جافاسكربت

    توفر لغة جافاسكربت عددًا من الدوال التي تسمح بالوصول إلى عناصر DOM، وهي متعددة بحسب الحاجة وطبيعة العنصر المراد التعامل معه.

    1. getElementById()

    تُستخدم هذه الدالة للحصول على عنصر واحد من خلال معرفه id.

    javascript
    var element = document.getElementById("myId");

    2. getElementsByClassName()

    ترجع مجموعة من العناصر التي تشترك في نفس اسم الصنف (class).

    javascript
    var items = document.getElementsByClassName("item");

    3. getElementsByTagName()

    ترجع جميع العناصر التي تحمل اسم وسم معين مثل

    .

    javascript
    var paragraphs = document.getElementsByTagName("p");

    4. querySelector() و querySelectorAll()

    توفران مرونة أكبر باستخدام محددات CSS.

    javascript
    var firstButton = document.querySelector("button"); var allButtons = document.querySelectorAll("button");

    رابعًا: التعديل على عناصر DOM

    بمجرد الوصول إلى عنصر ما، يمكن تعديل محتواه، خصائصه، أو حتى هيكله.

    1. تعديل النص

    javascript
    var p = document.getElementById("myParagraph"); p.textContent = "تم التعديل.";

    2. تعديل HTML الداخلي

    javascript
    p.innerHTML = "نص جديد مع تنسيق.";

    3. تعديل الخصائص (Attributes)

    javascript
    var link = document.getElementById("myLink"); link.setAttribute("href", "https://www.example.com");

    4. تعديل الأنماط (Styles)

    javascript
    p.style.color = "red"; p.style.fontWeight = "bold";

    خامسًا: إنشاء عناصر جديدة وإضافتها إلى DOM

    يمكن إنشاء عناصر جديدة وربطها بالشجرة:

    javascript
    var newElement = document.createElement("div"); newElement.textContent = "عنصر جديد"; document.body.appendChild(newElement);

    وللإضافة داخل عنصر معين:

    javascript
    var container = document.getElementById("container"); container.appendChild(newElement);

    أو للإدراج قبل عنصر آخر:

    javascript
    container.insertBefore(newElement, container.firstChild);

    سادسًا: حذف عناصر من DOM

    javascript
    var element = document.getElementById("removeMe"); element.remove();

    أو باستخدام DOM التقليدي:

    javascript
    element.parentNode.removeChild(element);

    سابعًا: التعامل مع الأحداث (Event Handling)

    DOM يسمح بالاستماع والتفاعل مع أحداث المستخدم كالنقر والتمرير والضغط على المفاتيح:

    javascript
    var btn = document.getElementById("myButton"); btn.addEventListener("click", function() { alert("تم النقر!"); });

    يمكن أيضًا إزالة المستمع:

    javascript
    btn.removeEventListener("click", handlerFunction);

    ثامنًا: التنقل بين عناصر DOM

    توجد خصائص عديدة تسمح بالتنقل بين العقد مثل:

    • parentNode – للوصول إلى العنصر الأب

    • childNodes – للوصول إلى الأبناء (تشمل النصوص والتعليقات)

    • children – للوصول إلى العناصر الأبناء فقط

    • firstChild / lastChild

    • nextSibling / previousSibling

    مثال:

    javascript
    var item = document.getElementById("item"); var parent = item.parentNode; var next = item.nextSibling;

    تاسعًا: أداء DOM وتحديث الصفحة

    تعديل DOM بشكل متكرر قد يسبب بطء الأداء بسبب ما يُعرف بإعادة التدفق (Reflow) وإعادة الطلاء (Repaint)، لذلك من الأفضل دائمًا تقليل العمليات المباشرة، واستخدام:

    • التجميع في DocumentFragment.

    • إجراء التعديلات خارج DOM ثم إدراجها دفعة واحدة.

    • استخدام innerHTML بحذر لتجنب المسائل الأمنية (XSS).


    عاشرًا: التعامل مع خصائص العقد والسمات

    العناصر في DOM تُمثل ككائنات، ويمكن التفاعل مع خصائصها بسهولة:

    javascript
    var input = document.getElementById("username"); input.value = "اسم المستخدم"; input.disabled = true;

    كما يمكن الوصول إلى السمات:

    javascript
    var link = document.getElementById("link"); var href = link.getAttribute("href");

    الحادي عشر: الجدول التوضيحي لعلاقات DOM وأوامر الوصول

    نوع العملية الأمر المستخدم الملاحظات
    الوصول بالـ ID getElementById("id") يُرجع عنصرًا واحدًا
    الوصول بالـ Class getElementsByClassName("class") يُرجع مجموعة HTMLCollection
    الوصول بالوسم getElementsByTagName("tag") يُرجع جميع العناصر من نفس النوع
    الوصول بالمحدد querySelector("selector") يُرجع أول عنصر يطابق CSS Selector
    إنشاء عنصر جديد document.createElement("tag") يجب إضافته للشجرة باستخدام append
    تعديل النص element.textContent لا يفسر HTML
    تعديل المحتوى HTML element.innerHTML يفسر HTML – يجب الحذر من إدخال المستخدم
    حذف عنصر element.remove() حديث نسبيًا، غير مدعوم في IE

    الثاني عشر: الاستخدامات الحديثة لـ DOM في التطبيقات التفاعلية

    في ظل تطور تطبيقات الويب الحديثة، أصبح التفاعل مع DOM لا يقتصر على التعديلات التقليدية، بل دخل في نطاقات متقدمة تشمل:

    • إنشاء واجهات ديناميكية بالكامل باستخدام DOM فقط (دون إعادة تحميل الصفحة).

    • استخدام DOM الافتراضي (Virtual DOM) كما في مكتبات React لتقليل إعادة الرسم.

    • التفاعل مع Web APIs كـ Drag & Drop، وMedia APIs، وCanvas، عبر DOM.

    • معالجة نماذج (Forms) بشكل ديناميكي حسب إدخال المستخدم.


    الثالث عشر: الاعتبارات الأمنية عند تعديل DOM

    تعديل DOM باستخدام innerHTML يمكن أن يعرض الصفحة لهجمات XSS (Cross Site Scripting) إذا لم تتم تنقية الإدخال جيدًا. لتفادي هذه المخاطر:

    • لا تستخدم innerHTML إلا مع محتوى موثوق.

    • استخدم textContent عندما لا تحتاج لتفسير HTML.

    • تحقق من كل إدخال يأتي من المستخدم قبل عرضه.

    • تجنب إنشاء عقد من سلاسل HTML خام، واستعمل DOM API بدلًا من ذلك.


    الرابع عشر: أدوات المطور في المتصفح واستكشاف DOM

    معظم المتصفحات الحديثة مثل Chrome وFirefox وEdge توفر أدوات للمطورين يمكن من خلالها استكشاف شجرة DOM مباشرة، وتعديلها بشكل حي، ومراقبة الأحداث وتغيّرات الشيفرة البرمجية. هذه الأدوات ضرورية لتصحيح الأخطاء وتحليل الأداء.

    يمكن فتحها بالضغط على F12، ثم الذهاب إلى تبويب “Elements” أو “Inspector”.


    المراجع:

    1. Mozilla Developer Network (MDN) – https://developer.mozilla.org

    2. W3C DOM Specification – https://www.w3.org/DOM